package com.yz.pay.mq;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.yz.common.resp.BaseResponse;
import com.yz.model.dto.order.PayOrderRequest;
import com.yz.common.constant.MQConstants;
import com.yz.model.entity.order.Order;
import com.yz.model.entity.promotion.PromotionCode;
import com.yz.pay.constant.PayConstant;
import com.yz.model.entity.pay.PayFlow;
import com.yz.pay.service.PayService;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

/**
 * Created With IntelliJ IDEA.
 * Descriptions:
 * <p>
 * User:Mr.Du
 * Date:2024/4/9
 * Time:13:43
 */
@Slf4j
@Component
public class PayMessageConsumer {

    @Resource
    private PayService payService;

    private Integer MAX_RETRY_COUNT = 3;

    private Integer cnt = 0;

    @SneakyThrows
    @RabbitListener(queues = {MQConstants.PAY_QUEUE_NAME}, ackMode = "MANUAL")
    public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {

        try{
            this.handleMessage(message, channel, deliveryTag);
            channel.basicAck(deliveryTag, false);
        }catch (Exception e){
            log.error("消息消费失败", e.getMessage());
            if(++cnt > MAX_RETRY_COUNT){
                channel.basicNack(deliveryTag, false, false);
            }else{
                channel.basicNack(deliveryTag, false, true);
            }
        }
    }

    @Transactional
    void handleMessage(String message, Channel channel, long deliveryTag) throws IOException {
        log.info("receiveMessage message = {}", message);
        if(StringUtils.isBlank(message)){
            channel.basicNack(deliveryTag, false, false);
            throw new RuntimeException("消息为空");
        }
        PayOrderRequest payOrderRequest = JSON.parseObject(message, PayOrderRequest.class);;
        PayFlow payFlow = PayFlow.builder()
                .subject(payOrderRequest.getSubject())
                .uid(payOrderRequest.getUid())
                .paySuccess(false)
                .totalAmount(payOrderRequest.getRealAmount())
                .outTradeNo(payOrderRequest.getId())
                .tradeStatus(PayConstant.WAIT_BUYER_PAY)
                .build();
        boolean save = payService.save(payFlow);
        if(!save){
            throw new RuntimeException("流水保存失败");
        }
    }
}